package cn.com.twoke.easyproject.aspect.request.lock;

import cn.com.twoke.easyproject.aspect.request.lock.hook.proceed.RequestLockKeyJoinPointProceed;
import cn.com.twoke.easyproject.common.utils.ExceptionUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.AnnotationUtils;

import java.lang.reflect.Method;

@Aspect
@Slf4j
@RequiredArgsConstructor
public class RequestLockAspect {

    /**
     * {@link RequestLockKeyGenerator}
     */
    private final RequestLockKeyGenerator keyGenerator;
    /**
     * {@link  RequestLockKeyJoinPointProceed}
     */
    private final RequestLockKeyJoinPointProceed joinPointProceed;

    @Around("execution(public * * (..)) && @annotation(cn.com.twoke.easyproject.aspect.request.lock.RequestLock)")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method method = methodSignature.getMethod();
        RequestLock requestLock = AnnotationUtils.findAnnotation(method, RequestLock.class);
        // 判断请求锁定是否开启
        if (requestLock.enabled()) {
            if (StringUtils.isEmpty(requestLock.prefix())) {
                ExceptionUtils.throwBusinessException("重复提交前缀不能为空");
            }
            // 生成的请求锁key
            String key = keyGenerator.generateKey(joinPoint, requestLock);
            return joinPointProceed.proceed(key, requestLock, joinPoint);
        } else {
            return joinPoint.proceed();
        }
    }

}
